package developerworks.jetty6;

import java.util.Collection;
import java.util.Hashtable;
import java.util.Iterator;

import javax.servlet.http.HttpSession;

import org.json.JSONArray;
import org.mortbay.util.ajax.Continuation;
import java.util.ArrayList;

import java.util.Timer;
import java.util.TimerTask;

import java.util.HashMap;
import java.util.Map;

public class Domain {
	
	private Collection<HttpSession> sessions;
	private HashMap<String, ArrayList<Inbox>> _inboxes;
	private HashMap<String, ArrayList<Continuation>> _continuations;
	public Domain() {
		_continuations = new HashMap<String, ArrayList<Continuation>>();
		_inboxes = new HashMap<String, ArrayList<Inbox>>();
	}


	public void addInbox(Inbox u){
		synchronized (_inboxes) {
			ArrayList<Inbox> is = _inboxes.get(u.call_id);
			if(is == null){
				is = new ArrayList<Inbox>();
				_inboxes.put(u.call_id, is);
			}
			is.add(u);
		}
	}
	public void removeInbox(Inbox i){
		synchronized (_inboxes) {
			ArrayList<Inbox> is = _inboxes.get(i.call_id);
			is.remove(i);
			if(is.isEmpty())
				_inboxes.get(i.call_id);
		}
		
	}
	public void addContinuation(Continuation c, HttpSession session, int timeoutSec ){
		Inbox user = (Inbox) session.getAttribute("Inbox");
		String call_id = user.call_id;
		
		//there could be multiple continuations for this call_id
		
		synchronized(_continuations) {
			ArrayList<Continuation> conts = _continuations.get(call_id);
			if(conts == null){
				conts = new ArrayList<Continuation>();
				_continuations.put(call_id, conts);
			}
			conts.add(c);
		}
		c.suspend(timeoutSec*1000);
	}
	
	public void newCRUDAll(CrudMessage o) {

		// a new user added could miss out on this message (but that is ok, he should have been here sooner!
		synchronized (_inboxes) {
			for(Iterator<Map.Entry <String, ArrayList<Inbox>>> iter = _inboxes.entrySet().iterator(); iter.hasNext();){
				Map.Entry<String, ArrayList<Inbox>> entry = iter.next();
				ArrayList<Inbox> inboxes = entry.getValue();
				for(Inbox i : inboxes){
					i.addObject(o);
				}
			}
		}
		synchronized (_continuations) {
			for(Iterator<Map.Entry <String, ArrayList<Continuation>>> iter = _continuations.entrySet().iterator(); iter.hasNext();){
				Map.Entry<String, ArrayList<Continuation>> entry = iter.next();
				ArrayList<Continuation> continuations = entry.getValue();
				for(Continuation c : continuations){
					c.resume();
				}
				//we could remove, but it will come back very soon.
			}
			_continuations.clear();
		}
	}
	
	public void newCRUDOne(CrudMessage o, String call_id){
		synchronized (_inboxes) {
			ArrayList<Inbox> inboxes = _inboxes.get(call_id);
			if(inboxes != null){
				for(Inbox i : inboxes){
					i.addObject(o);
				}
			}
		}
		synchronized (_continuations) {
			ArrayList<Continuation> continuations = _continuations.remove(call_id);
			if(continuations != null){
				for(Continuation c : continuations){
					c.resume();
				}
			}
		}
	}
	public void resumeContinuation(User u){
		synchronized (_continuations) {
			ArrayList<Continuation> continuations = _continuations.remove(u.call_id);
			if(continuations != null){
				for(Continuation c : continuations){
					c.resume();
				}
			}
		}
	}
}
